home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
VGX
/
shadows
/
bintoglo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
280 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
bintoglob.c - Spin 3D object file format to glo_object file format
converter.
Tim Heidmann, Silicon Graphics
June 26, 1991
*/
#include <stdio.h>
#include "fastobj.h"
#include "glo_obj.h"
#include "vect.h"
#define TRUE 1
#define FALSE 0
void
NoDups(glo_ObjPtr theObj, int nList, int nTriplets);
int
NoDegen(glo_ObjPtr theObj, int nList, int nTriplets);
main(int argc, char *argv[]) {
fastobj *myFObj;
glo_ObjPtr myGLObj;
int nTriplets, nQuads, nList, i, j, k, iTriplet;
int *pList;
float *pData;
char *inFile, *outFile;
int flipOrder;
if (argc == 3) {
flipOrder = FALSE;
inFile = argv[1]; outFile = argv[2];
} else if (argc == 4 && argv[1][0] == '-' && argv[1][1] == 'f') {
flipOrder = TRUE;
inFile = argv[2]; outFile = argv[3];
} else {
fprintf(stderr, "usage: %s [-f] <infile.bin> <outfile.glo>\n", argv[0]);
exit(1);
}
/* Read a .bin file */
myFObj = readfastobj(inFile);
printf("%s: %d points (%d polygons)\n", inFile,
myFObj->npoints, myFObj->npoints/4);
/* Convert fastobj structure to glo_object */
nTriplets = myFObj->npoints*2;
nQuads = myFObj->npoints/4;
if (myFObj->colors)
/* Color per vertex. Ignore colors. */
nList = 1 + (2 + 4) * nQuads + 1;
else
/* Normal per vertex. Use them. */
nList = 1 + (2 + 4 + 4) * nQuads + 1;
myGLObj = (glo_ObjPtr) malloc(sizeof(glo_ObjTyp));
myGLObj->list = (int *) malloc(sizeof(int)*nList);
myGLObj->t = (float (*)[3]) malloc(sizeof(float) * 3 * nTriplets);
/* March through fastobj data, copying to vertex and command list */
pList = myGLObj->list;
pData = (float *) myFObj->data;
iTriplet = 0;
if (!myFObj->colors) {
/* Normal per vertex, keep it all */
printf("Normal per vertex\n");
*pList++ = NPERV;
for (i=0; i<nQuads; i++) {
*pList++ = BGNPOLY;
for (j=0; j<4; j++) {
/* Normal */
for (k=0; k<3; k++)
myGLObj->t[iTriplet][k] = *pData++;
pData++; /* fastobj keeps points as float[4]'s */
pList[2 * (flipOrder ? 3-j : j)] = iTriplet++;
/* Vertex */
for (k=0; k<3; k++)
myGLObj->t[iTriplet][k] = *pData++;
pData++; /* fastobj keeps points as float[4]'s */
pList[2 * (flipOrder ? 3-j : j) + 1] = iTriplet++;
}
pList += 8;
*pList++ = ENDPOLY;
}
*pList++ = ENDLIST;
} else {
/* Ignore color per vertex info */
printf("Color per vertex\n");
*pList++ = NONORM;
for (i=0; i<nQuads; i++) {
*pList++ = BGNPOLY;
for (j=0; j<4; j++) {
pData += 4; /* Skip over color info */
for (k=0; k<3; k++)
myGLObj->t[iTriplet][k] = *pData++;
pData++;
pList[flipOrder ? 3-j : j] = iTriplet++;
}
pList += 4;
*pList++ = ENDPOLY;
}
*pList++ = ENDLIST;
}
/* Remove duplicate triplets, and degenerate points and polys */
nTriplets = NoDupTrips(myGLObj, nList, nTriplets);
nList = NoDegen(myGLObj, nList, nTriplets);
/* Write the .glo file */
glo_WriteObj(myGLObj, outFile);
}
#define MARGIN 0.0005
int
NoDupTrips(glo_ObjPtr theObj, int nList, int nTriplets) {
/* Step through triplet list, eliminating duplicates. */
int i, iTrip, iList, iCheck, nDuplicates;
int *pList;
short *tripletMap, *uniqueFlag;
float (*pTrip)[3], (*pCheck)[3], (*pNew)[3], (*newT)[3];
/* Keep a map of old triplet indices to indices into the list
with the duplicate values removed.
Also keep a flag for each triplet for if it's unique and gets kept. */
tripletMap = (short *) malloc(sizeof(short) * nTriplets);
uniqueFlag = (short *) malloc(sizeof(short) * nTriplets);
/* Check for duplicate triplets. Remember a mapping for each one */
nDuplicates = 0;
for (iTrip=0, pTrip=theObj->t; iTrip<nTriplets; iTrip++, pTrip++) {
tripletMap[iTrip] = iTrip - nDuplicates;
uniqueFlag[iTrip] = TRUE;
for (iCheck=0, pCheck=theObj->t; iCheck<iTrip; iCheck++, pCheck++)
if (fabs((*pTrip)[0] - (*pCheck)[0]) < MARGIN &&
fabs((*pTrip)[1] - (*pCheck)[1]) < MARGIN &&
fabs((*pTrip)[2] - (*pCheck)[2]) < MARGIN) {
tripletMap[iTrip] = tripletMap[iCheck];
uniqueFlag[iTrip] = FALSE;
nDuplicates++;
break;
}
}
/* Condense the triplet list, keeping only unique values. */
for (iTrip=0; iTrip<nTriplets && uniqueFlag[iTrip]; iTrip++) ;
for (pNew = pTrip = theObj->t+iTrip; iTrip<nTriplets; iTrip++, pTrip++)
if (uniqueFlag[iTrip]) {
for (i=0; i<3; i++)
(*pNew)[i] = (*pTrip)[i];
pNew++;
}
/* Now reset indices in the list to point at the unique triplet */
for (iList=0, pList=theObj->list; iList<nList; iList++, pList++)
if (*pList >= 0) *pList = tripletMap[*pList];
/* Finally, free working memory and return. */
free(tripletMap);
free(uniqueFlag);
printf("%d duplicate triplets (out of %d)\n", nDuplicates, nTriplets);
return nTriplets - nDuplicates;
}
int
NoDegen(glo_ObjPtr theObj, int nList, int nTriplets) {
/* Find and eliminate degenerate polygons and polygon edges */
int nVertices, nDest, nThisDegenV, nDegenV, nDegenP;
int done, leadingNormal, pervNormal;
int firstVertex, firstNormal, lastVertex, lastNormal, thisVertex;
int *pStart, *pDest, *pList;
nDegenV = 0;
nDegenP = 0;
nDest = 0;
for (done = FALSE, pDest = pList = theObj->list;; ) {
/* Find the next element, copying commands, following mode changes */
for (;*pList < 0; *pDest++ = *pList++) {
nDest++;
switch (*pList) {
case NONORM: leadingNormal = FALSE; pervNormal = FALSE; break;
case NPERV: leadingNormal = FALSE; pervNormal = TRUE ; break;
case NPERP: leadingNormal = TRUE ; pervNormal = FALSE; break;
case ENDLIST: done = TRUE; break;
default: ;
}
}
if (done) break;
/* Remember start in case we need to undo this poly */
pStart = pDest;
/* Look at the first vertex */
if (leadingNormal) *pDest++ = *pList++;
if (pervNormal) firstNormal = lastNormal = *pList++;
firstVertex = lastVertex = *pList++;
/* Add each successive vertex, checking against the previous one */
nVertices = 0;
nThisDegenV = 0;
while (*pList >= 0) {
/* More vertices to check */
if (pervNormal) {
if (pList[1] != lastVertex) {
*pDest++ = lastNormal;
*pDest++ = lastVertex;
lastNormal = *pList++;
lastVertex = *pList++;
nVertices++;
}
else {
pList += 2;
nThisDegenV++;
}
} else {
if (pList[0] != lastVertex) {
*pDest++ = lastVertex;
lastVertex = *pList++;
nVertices++;
}
else {
pList++;
nThisDegenV++;
}
}
}
/* That was the last vertex. Check against first before adding. */
if (pervNormal) {
if (lastVertex != firstVertex) {
*pDest++ = lastNormal;
*pDest++ = lastVertex;
nVertices++;
}
else nThisDegenV++;
} else {
if (lastVertex != firstVertex) {
*pDest++ = lastVertex;
nVertices++;
}
else nThisDegenV++;
}
/* Check for and delete degenerate polygons */
if (nVertices<3) {
pDest = pStart - 1; /* Go back to before the BGN... */
nDest--;
pList++; /* And swallow the following END... */
nDegenP++;
}
else {
/* Good polygon, add to the tally */
nDest += leadingNormal?1:0 + pervNormal?2*nVertices:nVertices;
nDegenV += nThisDegenV;
}
}
printf("%d degenerate vertices, %d degenerate polygons removed.\n",
nDegenV, nDegenP);
return nDest;
}